package com.jy.appmarket.receiver;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.text.TextUtils;
import cn.jpush.android.api.JPushInterface;

import com.jy.appmarket.R;
import com.jy.appmarket.download.DownloadUtils;
import com.jy.appmarket.model.AppExtras;
import com.jy.appmarket.model.ImageExtras;
import com.jy.appmarket.model.PushExtras;
import com.jy.appmarket.model.PushMessage;
import com.jy.appmarket.model.TopicExtras;
import com.jy.appmarket.model.WebExtras;
import com.jy.appmarket.service.DaemonService;
import com.jy.appmarket.statistics.event.openPushEvent;
import com.jy.appmarket.statistics.event.receivePushEvent;
import com.jy.appmarket.statistics.umeng.myUmengStaticstics;
import com.jy.appmarket.utils.AppPackageInfo;
import com.jy.appmarket.utils.BadgeUtils;
import com.jy.appmarket.utils.JsonParser;
import com.jy.appmarket.utils.LogUtil;
import com.jy.appmarket.utils.NotificationUtil;
import com.jy.appmarket.utils.PackageUtils;
import com.jy.appmarket.utils.Settings;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.rad.statistics.android.StatisticsAgent;

/**
 * 自定义接收器
 * 
 * 如果不定义这个 Receiver，则： 1) 默认用户会打开主界面 2) 接收不到自定义消息
 */
public class PushReceiver extends BroadcastReceiver {
	private static final String TAG = "JPush";
	public static final int NOTIFICATION_WEB_ID = 1111;
	public static final int NOTIFICATION_APP_ID = 1112;
	public static final int NOTIFICATION_TOPIC_ID = 1113;
	public static final int NOTIFICATION_OPEN_APP_ID = 1115;
	public static final int NOTIFICATION_IMAGE_WEB_ID = 1116;
	public static final int NOTIFICATION_IMAGE_APP_ID = 1117;
	public static final int NOTIFICATION_IMAGE_TOPIC_ID = 1118;
	public static final int NOTIFICATION_IMAGE_OPEN_APP_ID = 1119;

	private static final int NOTIFICATION_STYLE_TEXT = 0; // notification显示文本
	private static final int NOTIFICATION_STYLE_IMAGE = 1; // notification显示图片

	private static final String PUSH_ID = "push_id";
	private static final String RESULT_CODE = "result_code";
	private static final String TYPE_APP = "app"; // 应用
	private static final String TYPE_WEB = "web"; // web view
	private static final String TYPE_TOPIC = "topic"; // 专题
	private static final String TYPE_OPEN_APP = "open_app"; // open app
	private static final String TYPE_IMAGE = "image"; // 图片

	@Override
	public void onReceive(Context context, Intent intent) {
		Bundle bundle = intent.getExtras();
		LogUtil.d(TAG, "[MyReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle(bundle));

		if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
			String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);
			LogUtil.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);
			// send the Registration Id to your server...

		} else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
			LogUtil.d(TAG, "[MyReceiver] 接收到推送下来的自定义消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));
			processCustomMessage(context, bundle);
		} else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
			LogUtil.d(TAG, "[MyReceiver] 接收到推送下来的通知");
			int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);
			LogUtil.d(TAG, "[MyReceiver] 接收到推送下来的通知的ID: " + notifactionId);

		} else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
			LogUtil.d(TAG, "[MyReceiver] 用户点击打开了通知");
			StatisticsAgent.onEvent(context,
					new openPushEvent(intent.getStringExtra(PUSH_ID), intent.getIntExtra(RESULT_CODE, 0) + ""));
			myUmengStaticstics.openPush(context);

		} else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) {
			LogUtil.d(TAG, "[MyReceiver] 用户收到到RICH PUSH CALLBACK: " + bundle.getString(JPushInterface.EXTRA_EXTRA));
			// 在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码，比如打开新的Activity，
			// 打开一个网页等..

		} else if (JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction())) {
			boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false);
			LogUtil.e(TAG, "[MyReceiver]" + intent.getAction() + " connected state change to " + connected);
		} else {
			LogUtil.d(TAG, "[MyReceiver] Unhandled intent - " + intent.getAction());
		}
	}

	private void sendCancelNotificationBroadcastReceiver(Context context, long validTime, int notificationId) {
		Intent intent = new Intent(CancelNotificationReceiver.CANCEL_NOTIFICATION);
		intent.putExtra(CancelNotificationReceiver.NOTIFICATION_ID, notificationId);
		PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
		AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
		am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + validTime, pi);
	}

	// 打印所有的 intent extra 数据
	private static String printBundle(Bundle bundle) {
		StringBuilder sb = new StringBuilder();
		for (String key : bundle.keySet()) {
			if (key.equals(JPushInterface.EXTRA_NOTIFICATION_ID)) {
				sb.append("\nkey:" + key + ", value:" + bundle.getInt(key));
			} else if (key.equals(JPushInterface.EXTRA_CONNECTION_CHANGE)) {
				sb.append("\nkey:" + key + ", value:" + bundle.getBoolean(key));
			} else {
				sb.append("\nkey:" + key + ", value:" + bundle.getString(key));
			}
		}
		return sb.toString();
	}

	private void processCustomMessage(Context context, Bundle bundle) {
		CustomMessageExecutor executor = new CustomMessageExecutor(context, bundle);
		new Thread(executor).start();
	}

	private void showOpenAppPush(Context context, String title, String content, AppExtras extras,
			int notification_style, long validTime, Bitmap bm) {
		if (AppPackageInfo.getApplicationInfo(context, extras.getPkgName()) != null) {
			if (extras.isShow()) {
				if (BadgeUtils.isSupportBadge() && extras.isShowBadge() && !TextUtils.isEmpty(extras.getPkgName())) {
					addBadge(context, extras.getPkgName());
				}
				if (notification_style == NOTIFICATION_STYLE_TEXT) {
					NotificationUtil.showOpenAppNotification(context, NOTIFICATION_OPEN_APP_ID, title, content, extras);
					sendCancelNotificationBroadcastReceiver(context, validTime, NOTIFICATION_OPEN_APP_ID);
				} else if (notification_style == NOTIFICATION_STYLE_IMAGE) {
					NotificationUtil.showImageOpenAppNotifiation(context, NOTIFICATION_IMAGE_OPEN_APP_ID, title,
							content, extras, bm);
					sendCancelNotificationBroadcastReceiver(context, validTime, NOTIFICATION_IMAGE_OPEN_APP_ID);
				}
			} else {
				openApp(context, extras.getPkgName());
				sendConsumeBroadcast(context, extras.getPushId(), 0);
			}
		}
	}

	private void showWebViewPush(Context context, String title, String content, WebExtras extras,
			int notification_style, long validTime, Bitmap bm) {
		String webUrl = extras.getUrl();

		if (!TextUtils.isEmpty(webUrl) && webUrl.startsWith("http")) {
			if (notification_style == NOTIFICATION_STYLE_TEXT) {
				NotificationUtil.showWebViewNotification(context, NOTIFICATION_WEB_ID, title, content, extras);
				sendCancelNotificationBroadcastReceiver(context, validTime, NOTIFICATION_WEB_ID);
			} else if (notification_style == NOTIFICATION_STYLE_IMAGE) {
				NotificationUtil.showImageWebViewNotification(context, NOTIFICATION_IMAGE_WEB_ID, title, content,
						extras, bm);
				sendCancelNotificationBroadcastReceiver(context, validTime, NOTIFICATION_IMAGE_WEB_ID);
			}
		}
	}

	private void showTopicPush(Context context, String title, String content, TopicExtras extras,
			int notification_style, long validTime, Bitmap bm) {
		if (notification_style == NOTIFICATION_STYLE_TEXT) {
			NotificationUtil.showTopicNotification(context, NOTIFICATION_TOPIC_ID, title, content, extras);
			sendCancelNotificationBroadcastReceiver(context, validTime, NOTIFICATION_TOPIC_ID);
		} else if (notification_style == NOTIFICATION_STYLE_IMAGE) {
			NotificationUtil.showImageTopicNotification(context, NOTIFICATION_IMAGE_TOPIC_ID, title, content, extras,
					bm);
			sendCancelNotificationBroadcastReceiver(context, validTime, NOTIFICATION_IMAGE_TOPIC_ID);
		}
	}

	private void showAppPush(Context context, String title, String content, AppExtras extras, int notification_style,
			long validTime, Bitmap bm) {
		if (extras == null || TextUtils.isEmpty(extras.getPkgName())) {
			LogUtil.w(TAG, "showAppPush invalid arguments");
			return;
		}
		final AppExtras appExtras = extras;

		String pkgName = appExtras.getPkgName();
		// 是否安装
		if (PackageUtils.isPackageInstalled(context, pkgName)) {
			// 显示通知栏为打开
			if (BadgeUtils.isSupportBadge() && appExtras.isShowBadge() && !TextUtils.isEmpty(appExtras.getPkgName())) {
				addBadge(context, appExtras.getPkgName());
			}
			if (notification_style == NOTIFICATION_STYLE_TEXT) {
				NotificationUtil.showPushAppNotification(context, NOTIFICATION_APP_ID, title, content,
						context.getString(R.string.notification_detail), context.getString(R.string.open), appExtras,
						AppActionReceiver.ACTION_OPEN);
				sendCancelNotificationBroadcastReceiver(context, validTime, NOTIFICATION_APP_ID);
			} else if (notification_style == NOTIFICATION_STYLE_IMAGE) {
				NotificationUtil.showImageAppNotification(context, NOTIFICATION_IMAGE_APP_ID, title, content, appExtras,
						bm);
				sendCancelNotificationBroadcastReceiver(context, validTime, NOTIFICATION_IMAGE_APP_ID);
			}
		} else {
			if (notification_style == NOTIFICATION_STYLE_TEXT) {
				// 是否下载完成
				if (isAppDownLoadFinish(context, appExtras.getPkgName(), appExtras.getVersionCode())) {
					// 显示为安装
					NotificationUtil.showPushAppNotification(context, NOTIFICATION_APP_ID, title, content,
							context.getString(R.string.notification_detail), context.getString(R.string.install),
							appExtras, AppActionReceiver.ACTION_INSTALL);
					sendCancelNotificationBroadcastReceiver(context, validTime, NOTIFICATION_APP_ID);
				} else {
					// 显示为下载
					NotificationUtil.showPushAppNotification(context, NOTIFICATION_APP_ID, title, content,
							context.getString(R.string.notification_detail), context.getString(R.string.download),
							appExtras, AppActionReceiver.ACTION_DOWNLOAD);
					sendCancelNotificationBroadcastReceiver(context, validTime, NOTIFICATION_APP_ID);
				}
			} else if (notification_style == NOTIFICATION_STYLE_IMAGE) {
				NotificationUtil.showImageAppNotification(context, NOTIFICATION_IMAGE_APP_ID, title, content, appExtras,
						bm);
				sendCancelNotificationBroadcastReceiver(context, validTime, NOTIFICATION_IMAGE_APP_ID);
			}

		}
	}

	// 图片push在通知栏显示下载下来的图片，点击通知之后根据type不同，对应执行web,app,open_app,topic的操作
	private void processImageTypePush(Context context, ImageExtras imageExtras, String push_title, String push_content,
			long validTime) {
		// API level 16 开始支持
		if (android.os.Build.VERSION.SDK_INT < 16) {
			return;
		}

		String type = imageExtras.getType();
		String image_url = imageExtras.getImage_url();

		Bitmap img = ImageLoader.getInstance().loadImageSync(image_url);
		if (img != null) {
			if (TYPE_WEB.equalsIgnoreCase(type)) { // webview
				if (imageExtras.getWebExtras() instanceof WebExtras) {
					WebExtras extras = imageExtras.getWebExtras();
					extras.setPushId(imageExtras.getPushId());
					showWebViewPush(context, push_title, push_content, extras, NOTIFICATION_STYLE_IMAGE, validTime,
							img);
				}
			} else if (TYPE_TOPIC.equalsIgnoreCase(type)) { // 专题
				if (imageExtras.getTopicExtras() instanceof TopicExtras) {
					TopicExtras extras = imageExtras.getTopicExtras();
					extras.setPushId(imageExtras.getPushId());
					showTopicPush(context, push_title, push_content, extras, NOTIFICATION_STYLE_IMAGE, validTime, img);
				}
			} else if (TYPE_OPEN_APP.equalsIgnoreCase(type)) { // open app
				if (imageExtras.getAppExtras() instanceof AppExtras) {
					AppExtras extras = imageExtras.getAppExtras();
					extras.setPushId(imageExtras.getPushId());
					showOpenAppPush(context, push_title, push_content, extras, NOTIFICATION_STYLE_IMAGE, validTime,
							img);
				}
			} else if (TYPE_APP.equalsIgnoreCase(type)) { // app
				if (imageExtras.getAppExtras() instanceof AppExtras) {
					AppExtras extras = imageExtras.getAppExtras();
					extras.setPushId(imageExtras.getPushId());
					showAppPush(context, push_title, push_content, extras, NOTIFICATION_STYLE_IMAGE, validTime, img);
				}
			}
		}
	}

	class CustomMessageExecutor implements Runnable {
		Context context;
		Bundle bundle;

		public CustomMessageExecutor(Context context, Bundle bundle) {
			this.context = context;
			this.bundle = bundle;
		}

		@Override
		public void run() {
			PushMessage pushMessage = parseMessage(bundle);
			if (pushMessage == null) {
				LogUtil.d(TAG, "push message is null");
				return;
			}
			if (pushMessage.getExtras() == null || pushMessage.getExtras().getExpireTime() == null) {
				return;
			}
			long validTime = validTime(pushMessage.getExtras().getExpireTime());
			if (validTime <= 0) {
				LogUtil.d(TAG, "push massage is expire");
				myUmengStaticstics.receivePassTimePush(context, pushMessage.getContentType());
				StatisticsAgent.onEvent(context, new receivePushEvent(pushMessage.getExtras().getPushId(), "expire"));
				return;
			}
			String title = pushMessage.getTitle();
			String content = pushMessage.getMsgContent();
			StatisticsAgent.onEvent(context, new receivePushEvent(pushMessage.getExtras().getPushId(), null));
			myUmengStaticstics.receivePush(context, pushMessage.getContentType());
			if (TYPE_WEB.equalsIgnoreCase(pushMessage.getContentType())) {
				if (pushMessage.getExtras() instanceof WebExtras) {
					showWebViewPush(context, title, content, (WebExtras) pushMessage.getExtras(),
							NOTIFICATION_STYLE_TEXT, validTime, null);
				}
			} else if (TYPE_APP.equalsIgnoreCase(pushMessage.getContentType())) {
				if (pushMessage.getExtras() instanceof AppExtras) {
					AppExtras appExtras = (AppExtras) pushMessage.getExtras();
					showAppPush(context, title, content, appExtras, NOTIFICATION_STYLE_TEXT, validTime, null);
				}
			} else if (TYPE_TOPIC.equalsIgnoreCase(pushMessage.getContentType())) {
				if (pushMessage.getExtras() instanceof TopicExtras) {
					TopicExtras topicExtras = (TopicExtras) pushMessage.getExtras();
					showTopicPush(context, title, content, topicExtras, NOTIFICATION_STYLE_TEXT, validTime, null);
				}
			} else if (TYPE_OPEN_APP.equalsIgnoreCase(pushMessage.getContentType())) {
				if (pushMessage.getExtras() instanceof AppExtras) {
					AppExtras extras = (AppExtras) pushMessage.getExtras();
					showOpenAppPush(context, title, content, extras, NOTIFICATION_STYLE_TEXT, validTime, null);
				}
			} else if (TYPE_IMAGE.equalsIgnoreCase(pushMessage.getContentType())) {
				if (pushMessage.getExtras() instanceof ImageExtras) {
					ImageExtras imageExtras = (ImageExtras) pushMessage.getExtras();
					processImageTypePush(context, imageExtras, title, content, validTime);
				}
			}
		}
	}

	private void addBadge(Context context, String pkg) {
		synchronized (DaemonService.sLock) {
			Set<String> pkgs = Settings.getBadgePkgs(context);
			if (pkgs == null) {
				pkgs = new HashSet<String>();
			}
			pkgs.add(pkg);
			Settings.setBadgePkgs(context, pkgs);
		}
		String cls = BadgeUtils.getLaunchClass(context, pkg);
		BadgeUtils.showBadge(context, pkg, cls);
		context.startService(new Intent(context, DaemonService.class));
	}

	public static void sendConsumeBroadcast(Context context, String pushId, int resCode) {
		Intent i = new Intent(JPushInterface.ACTION_NOTIFICATION_OPENED);
		i.putExtra(PUSH_ID, pushId);
		i.putExtra(RESULT_CODE, resCode);
		context.sendBroadcast(i);
	}

	private long validTime(String expireTime) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm");
		try {
			Date expireDate = sdf.parse(expireTime);
			Date currentdate = new Date();
			return (expireDate.getTime() - currentdate.getTime());
		} catch (ParseException e) {
			LogUtil.e(TAG, "Dateformat.parser exception");
			e.printStackTrace();
		}
		return -1;
	}

	private boolean openApp(Context context, String pkgName) {
		try {
			Intent intent = context.getPackageManager().getLaunchIntentForPackage(pkgName);
			context.startActivity(intent);
			return true;
		} catch (Exception e) {
		}
		return false;
	}

	private boolean isAppDownLoadFinish(Context context, String pkgName, int versionCode) {
		String dlId = DownloadUtils.generateDownloadId(pkgName, versionCode);
		String path = DownloadUtils.getDownloadApkFilePathById(dlId);
		if (!TextUtils.isEmpty(path)) {
			return false;
		}

		File apk = new File(path);
		return apk.exists();
	}

	private PushMessage parseMessage(Bundle bundle) {
		PushMessage pushMessage = new PushMessage();
		pushMessage.setTitle(bundle.getString(JPushInterface.EXTRA_TITLE));
		pushMessage.setContentType(bundle.getString(JPushInterface.EXTRA_CONTENT_TYPE));
		pushMessage.setMsgContent(bundle.getString(JPushInterface.EXTRA_MESSAGE));
		String json = bundle.getString(JPushInterface.EXTRA_EXTRA);

		PushExtras extras = null;
		try {
			Class<?> cls = null;
			if ("web".equalsIgnoreCase(pushMessage.getContentType())) {
				cls = WebExtras.class;
			} else if ("app".equalsIgnoreCase(pushMessage.getContentType())) {
				cls = AppExtras.class;
			} else if ("topic".equalsIgnoreCase(pushMessage.getContentType())) {
				cls = TopicExtras.class;
			} else if ("open_app".equalsIgnoreCase(pushMessage.getContentType())) {
				cls = AppExtras.class;
			} else if ("image".equalsIgnoreCase(pushMessage.getContentType())) { // 增加图片类型
				cls = ImageExtras.class;
			} else {
				return null;
			}
			extras = (PushExtras) JsonParser.getJsonParse().parseJson(json, cls);
			pushMessage.setExtras(extras);
			return pushMessage;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
